<script setup>
  import { ref, reactive } from 'vue'
  import Graph3D from './components/Graph3D.vue'
  import Graph2D from './components/Graph2D.vue'
  import KnowledgeEditor from './components/KnowledgeEditor.vue'

  const currentView = ref('3d')
  const saveStatus = ref('') // '', 'success', 'error'

  // 全局响应式知识点数据
  const knowledgeList = ref([
    { id: '1', name: 'Vue.js 概述', parentId: null, prerequisites: [], postrequisites: [], relations: [] },
    { id: '1-1', name: '什么是Vue.js', parentId: '1', prerequisites: [], postrequisites: [], relations: [] },
    { id: '1-2', name: 'Vue.js的优势', parentId: '1', prerequisites: [], postrequisites: [], relations: [] },
    { id: '1-1-1', name: 'JavaScript基础', parentId: '1-1', prerequisites: [], postrequisites: [], relations: [] }
  ])

  // 全局响应式数据（节点/连线/掌握状态）
  function generateGraphData(knowledgeList) {
    console.log('【调试】generateGraphData 入参 knowledgeList:', JSON.parse(JSON.stringify(knowledgeList)));
    // 动态根据知识点数据生成 nodes 和 links
    const nodes = knowledgeList.map(item => ({
      id: item.id,
      label: item.name && item.name.trim() ? item.name : item.id,
      parentId: item.parentId,
      // level 字段后面补充
    }))

    console.log('【调试】generateGraphData 生成的nodes:', JSON.parse(JSON.stringify(nodes)));

    // 计算level
    const nodeMap = new Map(nodes.map(n => [n.id, n]));
    function getLevel(node) {
      if (node.parentId == null) return 0;
      const parent = nodeMap.get(node.parentId);
      return parent ? getLevel(parent) + 1 : 0;
    }
    nodes.forEach(node => {
      node.level = getLevel(node);
      node.z = node.level * 400 + Math.random() * 100; // z轴空间放大，和x/y一致
    });
    const links = []
    // 1. 自动添加树结构的父子连接线
    knowledgeList.forEach(item => {
      if (item.parentId) {
        links.push({ source: item.parentId, target: item.id, type: 'tree' })
      }
    })
    // 2. 再加上已有的"关系设置"links
    knowledgeList.forEach(item => {
      // 前置关系
      if (item.prerequisites && item.prerequisites.length) {
        item.prerequisites.forEach(pid => {
          links.push({ source: pid, target: item.id, type: 'prerequisite' })
        })
      }
      // 后置关系
      if (item.postrequisites && item.postrequisites.length) {
        item.postrequisites.forEach(pid => {
          links.push({ source: item.id, target: pid, type: 'postrequisite' })
        })
      }
      // 关联关系
      if (item.relations && item.relations.length) {
        item.relations.forEach(rid => {
          links.push({ source: item.id, target: rid, type: 'relation' })
        })
      }
    })
    return { nodes, links }
  }

  // const graphData = reactive(generateGraphData()) // 注释静态数据
  const graphData = ref({ nodes: [], links: [] })

  function onSaveKnowledge(newList) {
    knowledgeList.value = JSON.parse(JSON.stringify(newList)); // 替换引用
    graphData.value = generateGraphData(knowledgeList.value);
    saveStatus.value = 'success';
    setTimeout(() => { saveStatus.value = '' }, 2000);
  }
</script>

<template>
  <div id="app">
    <div v-if="saveStatus === 'success'" class="save-toast toast-success">保存成功</div>
    <div v-if="saveStatus === 'error'" class="save-toast toast-error">保存失败</div>
    <Graph3D v-if="currentView === '3d'" :graphData="graphData" />
    <Graph2D v-if="currentView === '2d'" :graphData="graphData" />
    <KnowledgeEditor v-if="currentView === 'editor'" :knowledge-list="knowledgeList" @save="onSaveKnowledge" />
    <div class="switch-buttons">
      <button :class="{ active: currentView === '2d' }" @click="currentView = '2d'">图谱</button>
      <button :class="{ active: currentView === '3d' }" @click="currentView = '3d'">3D图谱</button>
      <button :class="{ active: currentView === 'editor' }" @click="currentView = 'editor'">编辑知识点</button>
    </div>
  </div>
</template>

<style scoped>
  .logo {
    height: 6em;
    padding: 1.5em;
    will-change: filter;
    transition: filter 300ms;
  }

  .logo:hover {
    filter: drop-shadow(0 0 2em #646cffaa);
  }

  .logo.vue:hover {
    filter: drop-shadow(0 0 2em #42b883aa);
  }

  #app {
    width: 100vw;
    height: 100vh;
    position: relative;
  }

  .switch-buttons {
    position: fixed;
    top: 50%;
    right: 60px;
    transform: translateY(-50%);
    display: flex;
    flex-direction: column;
    z-index: 20;
  }

  .switch-buttons button {
    width: 105px;
    height: 40px;
    margin-bottom: 12px;
    background: #232c3b;
    color: #fff;
    border: none;
    border-radius: 12px;
    font-size: 18px;
    cursor: pointer;
    outline: none;
    transition: background 0.2s, color 0.2s;
  }

  .switch-buttons button.active {
    background: #3a7afe;
    color: #fff;
  }

  .switch-buttons button:last-child {
    margin-bottom: 0;
  }

  .save-toast {
    position: fixed;
    top: 40px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 9999;
    min-width: 120px;
    padding: 14px 32px;
    border-radius: 8px;
    font-size: 18px;
    text-align: center;
    box-shadow: 0 2px 12px #d0d8e0;
    color: #fff;
    opacity: 0.96;
  }

  .toast-success {
    background: #00b96b;
  }

  .toast-error {
    background: #ff4d4f;
  }
</style>